package com.it.schoolbookshop_back.service.impl;

import com.it.schoolbookshop_back.entities.dto.OrderGenerateDTO;
import com.it.schoolbookshop_back.entities.po.Book;
import com.it.schoolbookshop_back.entities.po.Transaction;
import com.it.schoolbookshop_back.entities.po.User;
import com.it.schoolbookshop_back.entities.vo.BookItemVO;
import com.it.schoolbookshop_back.entities.vo.OrderDetailVO;
import com.it.schoolbookshop_back.entities.vo.OrderGenerateVO;
import com.it.schoolbookshop_back.enums.BookStatusEnum;
import com.it.schoolbookshop_back.enums.OrderStatusEnum;
import com.it.schoolbookshop_back.mapper.BookMapper;
import com.it.schoolbookshop_back.mapper.OrderMapper;
import com.it.schoolbookshop_back.mapper.UserMapper;
import com.it.schoolbookshop_back.service.OrderService;
import com.it.schoolbookshop_back.utils.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单服务实现类
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private BookMapper bookMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    /**
     * 雪花算法ID生成器
     */
    private static final SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(0, 0);
    
    /**
     * 服务费率 0.05%
     */
    private static final BigDecimal SERVICE_CHARGE_RATE = new BigDecimal("0.0005");
    
    @Override
    @Transactional
    public OrderGenerateVO generateOrder(OrderGenerateDTO orderGenerateDTO, Integer buyerId) {
        // 参数校验
        if (orderGenerateDTO == null || orderGenerateDTO.getBooks() == null || orderGenerateDTO.getBooks().isEmpty()) {
            throw new IllegalArgumentException("订单书籍列表不能为空");
        }
        
        // 获取书籍ID列表
        List<Integer> bookIds = orderGenerateDTO.getBooks().stream()
                .map(OrderGenerateDTO.BookItem::getBookId)
                .collect(Collectors.toList());
        
        // 生成订单号
        String orderId = generateOrderId();
        
        // 处理每一本书籍
        List<Transaction> transactions = new ArrayList<>();
        List<BookItemVO> bookItems = new ArrayList<>();
        BigDecimal totalBookPrice = BigDecimal.ZERO;
        BigDecimal totalServiceCharge = BigDecimal.ZERO;
        
        for (Integer bookId : bookIds) {
            Book book = bookMapper.getBookById(bookId);
            
            // 验证书籍状态
            if (book == null || !BookStatusEnum.ACTIVE.name().toLowerCase().equals(book.getStatus())) {
                throw new IllegalArgumentException("书籍#" + bookId + "不存在或已被预定/售出");
            }
            
            // 检查用户是否尝试购买自己的书籍
            if (book.getSellerId().equals(buyerId)) {
                throw new IllegalArgumentException("不能购买自己发布的书籍#" + bookId);
            }
            
            // 计算服务费
            BigDecimal serviceCharge = book.getPrice().multiply(SERVICE_CHARGE_RATE)
                    .setScale(2, RoundingMode.HALF_UP);
            
            // 创建交易
            Transaction transaction = new Transaction();
            transaction.setOrderId(orderId);
            transaction.setBookId(bookId);
            transaction.setSellerId(book.getSellerId());
            transaction.setBuyerId(buyerId);
            transaction.setPrice(book.getPrice());
            transaction.setStatus(OrderStatusEnum.PENDING.getStatus());
            transaction.setRemark(orderGenerateDTO.getRemark());
            
            orderMapper.saveTransaction(transaction);
            transactions.add(transaction);
            
            // 修改书籍状态为reserved
            bookMapper.updateBookStatus(bookId, BookStatusEnum.RESERVED.name().toLowerCase());
            
            // 累加价格计算
            totalBookPrice = totalBookPrice.add(book.getPrice());
            totalServiceCharge = totalServiceCharge.add(serviceCharge);
            
            // 查询卖家信息
            User seller = userMapper.getUserById(book.getSellerId());
            
            // 构建书籍信息
            BookItemVO bookItemVO = BookItemVO.builder()
                    .title(book.getTitle())
                    .author(book.getAuthor())
                    .bookCondition(book.getBookCondition())
                    .price(book.getPrice())
                    .seller(seller.getUsername())
                    .build();
            
            bookItems.add(bookItemVO);
        }
        
        // 计算最终金额
        BigDecimal finalAmount = totalBookPrice.add(totalServiceCharge);
        
        // 构建返回结果
        return OrderGenerateVO.builder()
                .books(bookItems)
                .bookPrice(totalBookPrice)
                .serviceCharge(totalServiceCharge)
                .lastMoney(finalAmount)
                .build();
    }
    
    @Override
    public boolean cancelOrder(String orderId) {
        // 查询订单下的所有交易
        List<Transaction> transactions = orderMapper.getTransactionsByOrderId(orderId);
        if (transactions == null || transactions.isEmpty()) {
            log.warn("未找到订单：{}", orderId);
            return false;
        }
        
        // 检查是否所有交易都是pending状态
        boolean allPending = transactions.stream()
                .allMatch(t -> OrderStatusEnum.PENDING.getStatus().equals(t.getStatus()));
        
        if (!allPending) {
            log.warn("订单 {} 中存在非pending状态的交易，无法取消", orderId);
            return false;
        }
        
        // 更新所有该订单号的交易状态为已取消
        int result = orderMapper.updateTransactionStatusByOrderId(orderId, OrderStatusEnum.CANCELLED.getStatus());
        
        if (result > 0) {
            // 更新所有关联书籍的状态为active
            for (Transaction trans : transactions) {
                bookMapper.updateBookStatus(trans.getBookId(), BookStatusEnum.ACTIVE.name().toLowerCase());
            }
            
            log.info("订单 {} 已成功取消，共 {} 笔交易", orderId, transactions.size());
            return true;
        } else {
            log.warn("更新订单 {} 状态失败", orderId);
            return false;
        }
    }
    
    /**
     * 生成订单号
     */
    private String generateOrderId() {
        // 使用雪花算法生成订单号（带ORDER前缀）
        return snowflakeIdWorker.nextOrderId();
    }
    
    /**
     * 根据订单号查询所有交易
     */
    private List<Transaction> getTransactionsByOrderId(String orderId) {
        return orderMapper.getTransactionsByOrderId(orderId);
    }
    
    @Override
    public List<Map<String, Object>> getAllOrders(String status) {
        log.info("查询所有订单，状态筛选：{}", status);
        return orderMapper.getAllOrders(status);
    }
    
    @Override
    public List<Map<String, Object>> getUserOrders(Integer userId, String status) {
        log.info("查询用户[{}]的订单，状态筛选：{}", userId, status);
        return orderMapper.getUserOrders(userId, status);
    }
    
    @Override
    public boolean isOrderBelongsToUser(String orderId, Integer userId) {
        log.info("检查订单[{}]是否属于用户[{}]", orderId, userId);
        List<Transaction> transactions = orderMapper.getTransactionsByOrderId(orderId);
        
        if (transactions == null || transactions.isEmpty()) {
            return false;
        }
        
        // 检查订单中的所有交易是否都属于该用户
        return transactions.stream()
                .allMatch(t -> t.getBuyerId().equals(userId));
    }
    
    @Override
    public OrderDetailVO getOrderDetail(String orderId) {
        log.info("查询订单详情，订单号：{}", orderId);
        
        List<Map<String, Object>> detailMaps = orderMapper.getOrderDetailByOrderId(orderId);
        if (detailMaps == null || detailMaps.isEmpty()) {
            log.warn("未找到订单详情，订单号：{}", orderId);
            return new OrderDetailVO();
        }
        
        List<OrderDetailVO.BookDetail> bookDetails = detailMaps.stream()
                .map(map -> {
                    // 从Map中提取数据，构建BookDetail对象
                    return OrderDetailVO.BookDetail.builder()
                            .title((String) map.get("title"))
                            .author((String) map.get("author"))
                            .price((BigDecimal) map.get("price"))
                            .seller((String) map.get("seller"))
                            .department((String) map.get("department"))
                            .build();
                })
                .collect(Collectors.toList());
        
        return OrderDetailVO.builder()
                .book(bookDetails)
                .build();
    }
    
    @Override
    @Transactional
    public boolean payOrder(String orderId, Integer buyerId) {
        log.info("处理订单支付，订单号：{}，买家ID：{}", orderId, buyerId);
        
        // 获取订单下的所有交易
        List<Transaction> transactions = orderMapper.getTransactionsByOrderId(orderId);
        if (transactions == null || transactions.isEmpty()) {
            log.warn("未找到订单：{}", orderId);
            return false;
        }
        
        // 检查是否存在买家就是卖家的情况（不允许购买自己的书籍）
        boolean isBuyingOwnBooks = transactions.stream()
                .anyMatch(t -> t.getSellerId().equals(buyerId));

        if (isBuyingOwnBooks) {
            log.warn("用户 {} 尝试购买自己发布的书籍，操作被拒绝", buyerId);
            return false;
        }
        
        // 检查是否所有交易都是pending状态
        boolean allPending = transactions.stream()
                .allMatch(t -> OrderStatusEnum.PENDING.getStatus().equals(t.getStatus()));
        
        if (!allPending) {
            log.warn("订单 {} 中存在非pending状态的交易，无法支付", orderId);
            return false;
        }
        
        // 检查买家是否有权限支付该订单
        boolean isBuyerValid = transactions.stream()
                .allMatch(t -> t.getBuyerId().equals(buyerId));
        
        if (!isBuyerValid) {
            log.warn("买家ID不匹配，无权支付订单 {}", orderId);
            return false;
        }
        
        // 计算订单总金额（书籍价格 + 服务费）
        BigDecimal totalBookPrice = BigDecimal.ZERO;
        for (Transaction transaction : transactions) {
            totalBookPrice = totalBookPrice.add(transaction.getPrice());
        }
        
        // 计算服务费
        BigDecimal totalServiceCharge = totalBookPrice.multiply(SERVICE_CHARGE_RATE)
                .setScale(2, RoundingMode.HALF_UP);
        
        // 计算总付款金额
        BigDecimal totalPayment = totalBookPrice.add(totalServiceCharge);
        
        // 获取买家信息
        User buyer = userMapper.getUserById(buyerId);
        if (buyer == null) {
            log.warn("未找到买家信息：{}", buyerId);
            return false;
        }
        
        // 检查买家余额是否足够
        if (buyer.getBalance() == null) {
            log.warn("买家余额为空，无法支付");
            return false;
        }

        BigDecimal buyerBalance = BigDecimal.valueOf(buyer.getBalance());
        if (buyerBalance.compareTo(totalPayment) < 0) {
            log.warn("买家余额不足，当前余额：{}，需支付：{}", buyerBalance, totalPayment);
            return false;
        }
        
        // 扣除买家余额
        BigDecimal newBuyerBalance = buyerBalance.subtract(totalPayment);
        int updateBuyerResult = userMapper.updateUserBalance(buyerId, newBuyerBalance);
        if (updateBuyerResult <= 0) {
            log.error("更新买家余额失败");
            throw new RuntimeException("更新买家余额失败");
        }
        
        // 更新所有订单状态为已完成
        int updateOrderResult = orderMapper.updateTransactionStatusByOrderId(orderId, OrderStatusEnum.COMPLETED.getStatus());
        if (updateOrderResult <= 0) {
            log.error("更新订单状态失败");
            throw new RuntimeException("更新订单状态失败");
        }
        
        // 更新所有书籍状态为已售出
        for (Transaction transaction : transactions) {
            int updateBookResult = bookMapper.updateBookStatus(transaction.getBookId(), BookStatusEnum.SOLD.name().toLowerCase());
            if (updateBookResult <= 0) {
                log.error("更新书籍 {} 状态失败", transaction.getBookId());
                throw new RuntimeException("更新书籍状态失败");
            }
            log.info("书籍 {} 状态已更新为已售出", transaction.getBookId());
            
            try {
                // 更新卖家统计数据：在售书籍数量减1
                userMapper.decrementBookCount(transaction.getSellerId());
                
                // 更新卖家统计数据：售出书籍数量加1
                userMapper.incrementSoldCount(transaction.getSellerId());
                
                log.info("卖家ID: {} 的书籍统计已更新: 在售书籍-1, 售出书籍+1", transaction.getSellerId());
            } catch (Exception e) {
                log.error("更新卖家统计数据失败: {}", e.getMessage(), e);
                // 不影响主流程
            }
        }
        
        try {
            // 更新买家统计数据：购买书籍数量增加
            userMapper.incrementBoughtCount(buyerId);
            log.info("买家ID: {} 的购买书籍数量已增加", buyerId);
        } catch (Exception e) {
            log.error("更新买家购买书籍数量失败: {}", e.getMessage(), e);
            // 不影响主流程
        }
        
        // 为每个卖家增加对应书籍的金额（不包含服务费）
        for (Transaction transaction : transactions) {
            // 获取卖家信息
            User seller = userMapper.getUserById(transaction.getSellerId());
            if (seller == null) {
                log.warn("未找到卖家信息：{}", transaction.getSellerId());
                continue;
            }
            
            // 计算卖家应得金额（书籍价格）
            BigDecimal sellerAmount = transaction.getPrice();
            
            // 更新卖家余额
            BigDecimal sellerBalance = seller.getBalance() == null ? 
                    BigDecimal.ZERO : BigDecimal.valueOf(seller.getBalance());
            BigDecimal newSellerBalance = sellerBalance.add(sellerAmount);
            
            int updateSellerResult = userMapper.updateUserBalance(transaction.getSellerId(), newSellerBalance);
            if (updateSellerResult <= 0) {
                log.error("更新卖家 {} 余额失败", transaction.getSellerId());
                throw new RuntimeException("更新卖家余额失败");
            }
        }
        
        log.info("订单 {} 支付成功，总金额：{}", orderId, totalPayment);
        return true;
    }
    
    @Override
    public Integer getSellerIdByOrderIdAndBookTitle(String orderId, String bookTitle) {
        log.info("查询订单[{}]中书籍[{}]的卖家ID", orderId, bookTitle);
        
        try {
            // 获取订单下的所有交易
            List<Transaction> transactions = orderMapper.getTransactionsByOrderId(orderId);
            if (transactions == null || transactions.isEmpty()) {
                log.warn("未找到订单：{}", orderId);
                return null;
            }
            
            // 遍历交易，查找匹配书籍标题的交易
            for (Transaction transaction : transactions) {
                Book book = bookMapper.getBookById(transaction.getBookId());
                if (book != null && book.getTitle().equals(bookTitle)) {
                    return transaction.getSellerId();
                }
            }
            
            log.warn("在订单[{}]中未找到书籍[{}]的卖家信息", orderId, bookTitle);
            return null;
        } catch (Exception e) {
            log.error("查询卖家ID失败: {}", e.getMessage(), e);
            return null;
        }
    }
}
